using AutoMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Work.API.Applications.Read.Commands;
using Work.API.Dtos;
using Work.ErrorCode;
using Work.Infrastructure.Interfaces;

namespace Work.API.Applications.Read.CommandHandlers
{
    /// <summary>
    /// 获取未支付患者列表处理器
    /// </summary>
    public class GetUnpaidPatientsQueryHandler : IRequestHandler<GetUnpaidPatientsQuery, ApiResult<List<UnpaidPatientDto>>>
    {
        private readonly IBaseRepository<Domain.Appintment> _appointmentRepo;
        private readonly IBaseRepository<Domain.Patient> _patientRepo;
        private readonly IBaseRepository<Domain.MedicalRecord> _medicalRecordRepo;
        private readonly IBaseRepository<Domain.PrescriptionItem> _prescriptionItemRepo;

        public GetUnpaidPatientsQueryHandler(
            IBaseRepository<Domain.Appintment> appointmentRepo,
            IBaseRepository<Domain.Patient> patientRepo,
            IBaseRepository<Domain.MedicalRecord> medicalRecordRepo,
            IBaseRepository<Domain.PrescriptionItem> prescriptionItemRepo)
        {
            _appointmentRepo = appointmentRepo;
            _patientRepo = patientRepo;
            _medicalRecordRepo = medicalRecordRepo;
            _prescriptionItemRepo = prescriptionItemRepo;
        }

        public async Task<ApiResult<List<UnpaidPatientDto>>> Handle(GetUnpaidPatientsQuery request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<List<UnpaidPatientDto>>();

            try
            {
                // 查询条件：
                // 1. 有预约记录
                // 2. 有病历且状态为"已完成"
                // 3. 有处方明细且PaymentStatus="未支付"
                // 4. 没有已支付的Payment记录（通过PrescriptionItem的PaymentStatus判断）

                var query = from a in _appointmentRepo.GetAll()
                            join p in _patientRepo.GetAll() on a.PatientId equals p.PatientId
                            join mr in _medicalRecordRepo.GetAll() on a.AppintmentId equals mr.AppointmentId
                            where mr.Status == "已完成"
                            where _prescriptionItemRepo.GetAll()
                                .Any(pi => pi.AppointmentId == a.AppintmentId && pi.PaymentStatus == "未支付")
                            select new UnpaidPatientDto
                            {
                                AppointmentId = a.AppintmentId,
                                RegistrationNum = a.RegistrationNum,
                                PatientName = p.PatientName,
                                GenderText = p.Gender ? "男" : "女",
                                Department = a.Department,
                                IdCard = p.IdCard,
                                PatientId = p.PatientId,
                                CardNumber = p.CardNumber
                            };

                // 添加过滤条件
                // 注意：已移除RegistrationNum的查询支持，只保留IdCard和PatientName
                
                if (!string.IsNullOrWhiteSpace(request.IdCard))
                {
                    // 精确匹配身份证号
                    query = query.Where(x => x.IdCard != null && x.IdCard == request.IdCard);
                }

                if (!string.IsNullOrWhiteSpace(request.PatientName))
                {
                    query = query.Where(x => x.PatientName != null && x.PatientName.Contains(request.PatientName));
                }

                var unpaidPatients = await query
                    .Distinct()
                    .OrderByDescending(x => x.AppointmentId)
                    .ToListAsync(cancellationToken);

                result.Code = ApiEnum.成功;
                result.Message = "查询成功";
                result.Data = unpaidPatients;
            }
            catch (System.Exception ex)
            {
                result.Code = ApiEnum.失败;
                result.Message = $"查询失败：{ex.Message}";
                result.Data = new List<UnpaidPatientDto>();
            }

            return result;
        }
    }
}

